<!DOCTYPE html>

<html>
<head>
  <title>regexp.js</title>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
  <link rel="stylesheet" media="all" href="../../../docco.css" />
</head>
<body>
  <div id="container">
    <div id="background"></div>
    
    <ul class="sections">
        
          <li id="title">
              <div class="annotation">
                  <h1>regexp.js</h1>
              </div>
          </li>
        
        
        
        <li id="section-1">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-1">&#182;</a>
              </div>
              <p>Regexp nodes are the entire regular expression. They consist of a collection
of <a href="./match.html">Match</a> nodes separated by <code>|</code>.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>
<span class="hljs-keyword">import</span> util <span class="hljs-keyword">from</span> <span class="hljs-string">'../../util.js'</span>;
<span class="hljs-keyword">import</span> _ <span class="hljs-keyword">from</span> <span class="hljs-string">'lodash'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
  <span class="hljs-attr">type</span>: <span class="hljs-string">'regexp'</span>,</pre></div></div>
            
        </li>
        
        
        <li id="section-2">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-2">&#182;</a>
              </div>
              <p>Renders the regexp into the currently set container.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  _render() {
    <span class="hljs-keyword">let</span> matchContainer = <span class="hljs-keyword">this</span>.container.group()
      .addClass(<span class="hljs-string">'regexp-matches'</span>)
      .transform(Snap.matrix()
        .translate(<span class="hljs-number">20</span>, <span class="hljs-number">0</span>));</pre></div></div>
            
        </li>
        
        
        <li id="section-3">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-3">&#182;</a>
              </div>
              <p>Renders each match into the match container.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-keyword">return</span> <span class="hljs-built_in">Promise</span>.all(_.map(<span class="hljs-keyword">this</span>.matches,
      match =&gt; match.render(matchContainer.group())
    ))
      .then(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
        <span class="hljs-keyword">let</span> containerBox,
            paths;</pre></div></div>
            
        </li>
        
        
        <li id="section-4">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-4">&#182;</a>
              </div>
              <p>Space matches vertically in the match container.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>        util.spaceVertically(<span class="hljs-keyword">this</span>.matches, {
          <span class="hljs-attr">padding</span>: <span class="hljs-number">5</span>
        });

        containerBox = <span class="hljs-keyword">this</span>.getBBox();</pre></div></div>
            
        </li>
        
        
        <li id="section-5">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-5">&#182;</a>
              </div>
              <p>Creates the curves from the side lines for each match.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>        paths = _.map(<span class="hljs-keyword">this</span>.matches, match =&gt; <span class="hljs-keyword">this</span>.makeCurve(containerBox, match));</pre></div></div>
            
        </li>
        
        
        <li id="section-6">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-6">&#182;</a>
              </div>
              <p>Add side lines to the list of paths.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>        paths.push(<span class="hljs-keyword">this</span>.makeSide(containerBox, _.first(<span class="hljs-keyword">this</span>.matches)));
        paths.push(<span class="hljs-keyword">this</span>.makeSide(containerBox, _.last(<span class="hljs-keyword">this</span>.matches)));</pre></div></div>
            
        </li>
        
        
        <li id="section-7">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-7">&#182;</a>
              </div>
              <p>Render connector paths.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>        <span class="hljs-keyword">this</span>.container.prepend(
          <span class="hljs-keyword">this</span>.container.path(_(paths).flatten().compact().values().join(<span class="hljs-string">''</span>)));

        containerBox = matchContainer.getBBox();</pre></div></div>
            
        </li>
        
        
        <li id="section-8">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-8">&#182;</a>
              </div>
              <p>Create connections from side lines to each match and render into
the match container.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>        paths = _.map(<span class="hljs-keyword">this</span>.matches, match =&gt; <span class="hljs-keyword">this</span>.makeConnector(containerBox, match));
        matchContainer.prepend(
          matchContainer.path(paths.join(<span class="hljs-string">''</span>)));
      });
  },</pre></div></div>
            
        </li>
        
        
        <li id="section-9">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-9">&#182;</a>
              </div>
              <p>Returns an array of SVG path strings to draw the vertical lines on the
left and right of the node.</p>
<ul>
<li><strong>containerBox</strong> - Bounding box of the container.</li>
<li><strong>match</strong> - Match node that the line will be drawn to.</li>
</ul>

            </div>
            
            <div class="content"><div class='highlight'><pre>  makeSide(containerBox, match) {
    <span class="hljs-keyword">let</span> box = match.getBBox(),
        distance = <span class="hljs-built_in">Math</span>.abs(box.ay - containerBox.cy);</pre></div></div>
            
        </li>
        
        
        <li id="section-10">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-10">&#182;</a>
              </div>
              <p>Only need to draw side lines if the match is more than 15 pixels from
the vertical center of the rendered regexp. Less that 15 pixels will be
handled by the curve directly.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-keyword">if</span> (distance &gt;= <span class="hljs-number">15</span>) {
      <span class="hljs-keyword">let</span> shift = (box.ay &gt; containerBox.cy) ? <span class="hljs-number">10</span> : <span class="hljs-number">-10</span>,
          edge = box.ay - shift;

      <span class="hljs-keyword">return</span> [
        <span class="hljs-string">`M0,<span class="hljs-subst">${containerBox.cy}</span>q10,0 10,<span class="hljs-subst">${shift}</span>V<span class="hljs-subst">${edge}</span>`</span>,
        <span class="hljs-string">`M<span class="hljs-subst">${containerBox.width + <span class="hljs-number">40</span>}</span>,<span class="hljs-subst">${containerBox.cy}</span>q-10,0 -10,<span class="hljs-subst">${shift}</span>V<span class="hljs-subst">${edge}</span>`</span>
      ];
    }
  },</pre></div></div>
            
        </li>
        
        
        <li id="section-11">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-11">&#182;</a>
              </div>
              <p>Returns an array of SVG path strings to draw the curves from the
sidelines up to the anchor of the match node.</p>
<ul>
<li><strong>containerBox</strong> - Bounding box of the container.</li>
<li><strong>match</strong> - Match node that the line will be drawn to.</li>
</ul>

            </div>
            
            <div class="content"><div class='highlight'><pre>  makeCurve(containerBox, match) {
    <span class="hljs-keyword">let</span> box = match.getBBox(),
        distance = <span class="hljs-built_in">Math</span>.abs(box.ay - containerBox.cy);

    <span class="hljs-keyword">if</span> (distance &gt;= <span class="hljs-number">15</span>) {</pre></div></div>
            
        </li>
        
        
        <li id="section-12">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-12">&#182;</a>
              </div>
              <p>For match nodes more than 15 pixels from the center of the regexp, a
quarter-circle curve is used to connect to the sideline.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      <span class="hljs-keyword">let</span> curve = (box.ay &gt; containerBox.cy) ? <span class="hljs-number">10</span> : <span class="hljs-number">-10</span>;

      <span class="hljs-keyword">return</span> [
        <span class="hljs-string">`M10,<span class="hljs-subst">${box.ay - curve}</span>q0,<span class="hljs-subst">${curve}</span> 10,<span class="hljs-subst">${curve}</span>`</span>,
        <span class="hljs-string">`M<span class="hljs-subst">${containerBox.width + <span class="hljs-number">30</span>}</span>,<span class="hljs-subst">${box.ay - curve}</span>q0,<span class="hljs-subst">${curve}</span> -10,<span class="hljs-subst">${curve}</span>`</span>
      ];
    } <span class="hljs-keyword">else</span> {</pre></div></div>
            
        </li>
        
        
        <li id="section-13">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-13">&#182;</a>
              </div>
              <p>For match nodes less than 15 pixels from the center of the regexp, a
slightly curved line is used to connect to the sideline.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      <span class="hljs-keyword">let</span> anchor = box.ay - containerBox.cy;

      <span class="hljs-keyword">return</span> [
        <span class="hljs-string">`M0,<span class="hljs-subst">${containerBox.cy}</span>c10,0 10,<span class="hljs-subst">${anchor}</span> 20,<span class="hljs-subst">${anchor}</span>`</span>,
        <span class="hljs-string">`M<span class="hljs-subst">${containerBox.width + <span class="hljs-number">40</span>}</span>,<span class="hljs-subst">${containerBox.cy}</span>c-10,0 -10,<span class="hljs-subst">${anchor}</span> -20,<span class="hljs-subst">${anchor}</span>`</span>
      ];
    }
  },</pre></div></div>
            
        </li>
        
        
        <li id="section-14">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-14">&#182;</a>
              </div>
              <p>Returns an array of SVG path strings to draw the connection from the
curve to match node.</p>
<ul>
<li><strong>containerBox</strong> - Bounding box of the container.</li>
<li><strong>match</strong> - Match node that the line will be drawn to.</li>
</ul>

            </div>
            
            <div class="content"><div class='highlight'><pre>  makeConnector(containerBox, match) {
    <span class="hljs-keyword">let</span> box = match.getBBox();

    <span class="hljs-keyword">return</span> <span class="hljs-string">`M0,<span class="hljs-subst">${box.ay}</span>h<span class="hljs-subst">${box.ax}</span>M<span class="hljs-subst">${box.ax2}</span>,<span class="hljs-subst">${box.ay}</span>H<span class="hljs-subst">${containerBox.width}</span>`</span>;
  },

  setup() {
    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.properties.alternates.elements.length === <span class="hljs-number">0</span>) {</pre></div></div>
            
        </li>
        
        
        <li id="section-15">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-15">&#182;</a>
              </div>
              <p>When there is only one match node to render, proxy to it.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      <span class="hljs-keyword">this</span>.proxy = <span class="hljs-keyword">this</span>.properties.match;
    } <span class="hljs-keyword">else</span> {</pre></div></div>
            
        </li>
        
        
        <li id="section-16">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-16">&#182;</a>
              </div>
              <p>Merge all the match nodes into one array.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      <span class="hljs-keyword">this</span>.matches = [<span class="hljs-keyword">this</span>.properties.match].concat(
        _.map(<span class="hljs-keyword">this</span>.properties.alternates.elements,
          element =&gt; element.properties.match)
      );
    }
  }
};</pre></div></div>
            
        </li>
        
    </ul>
  </div>
</body>
</html>
